unit uExportGuiEventCallbackpas;

interface
   uses Windows, Messages, SysUtils, Classes, Forms,
   Variants,   Graphics, Controls, Spin,
  Dialogs, ComCtrls, ToolWin, StdCtrls, ExtCtrls, Menus
   ;


   type



   
   //-------------------------------  type  ------------------------------------

   event_type =
   (

       EVENT_TYPE_FORM_UNDEFINED = 0,

       EVENT_TYPE_FORM_RESIZE,
       EVENT_TYPE_FORM_CLOSE,
       EVENT_TYPE_FORM_CLOSE_QUERY,
       EVENT_TYPE_FORM_PAINT,
       EVENT_TYPE_FORM_CLICK,
       EVENT_TYPE_FORM_DESTROY,
       EVENT_TYPE_FORM_ACTIVATE,
       EVENT_TYPE_FORM_SHOW,
       EVENT_TYPE_FORM_HIDE,

       EVENT_TYPE_FORM_MOUSEDOWN,
       EVENT_TYPE_FORM_MOUSEMOVE,
       EVENT_TYPE_FORM_MOUSEUP,

       //---------------------
 

       EVENT_TYPE_MAINMENUITEMCLICK,
       EVENT_TYPE_BUTTONCLICK,
       EVENT_TYPE_CHECKBOXCLICK,
       EVENT_TYPE_RADIOGROUPCLICK,
       EVENT_TYPE_EDITCHANGE,
       EVENT_TYPE_TRACKBARCHANGE,
       EVENT_TYPE_MEMOCHANGE,
       EVENT_TYPE_LISTBOXCLICK,
       EVENT_TYPE_UPDOWNCLICK,
       EVENT_TYPE_SPINEDITCHANGE,
       EVENT_TYPE_COMBOBOXCHANGE,
       EVENT_TYPE_PAGECONTROLCHANGE,
       EVENT_TYPE_FORM_POPUPMENUITEMCLICK,

       EVENT_TYPE_TREEVIEW_CHANGE,
       EVENT_TYPE_TREEVIEW_CLICK,
       EVENT_TYPE_TREEVIEW_COLLAPSED,
       EVENT_TYPE_TREEVIEW_EXPANDED,



       EVENT_TYPE_FORCE32 = $ffffffff


   );




  callback_info =  record // packed record
      pSender :Pointer;
      tag :integer;
      eventType :event_type;

      param1 :integer;
      param2 :integer;
      param3 :integer;

      class_name : array [0..31] of AnsiChar;
      name : array [0..31] of AnsiChar;



  end;

  pcallback_info = ^callback_info;


  FuncGuiEventCallBack = procedure(user_context :Pointer;
      const ci :pcallback_info); stdcall;


  FuncOnResizeForm = procedure(pForm :pointer; w :Integer; h :integer; user_context :pointer); stdcall;



//----------------------------------------------------------------------------

procedure SetGuiEventCallBack( func :FuncGuiEventCallBack; user_context :pointer); stdcall;

procedure SetFormOnResize(pForm :Pointer; func :FuncOnResizeForm; user_context :pointer); stdcall;

procedure PostExit(code :integer); stdcall;



type

THelper = class
public

  process_messages_result :Boolean;

  f_FuncGuiEventCallBack :FuncGuiEventCallBack;
  f_FuncGuiEventCallBack_user_context :pointer;

  f_callback_info : callback_info;

   constructor Create();
   destructor Destroy; override;

   procedure Reset( Sender: TObject );

   // ----------------------  form  events  ----------------------------------

   procedure OnFormResize(Sender: TObject);
   procedure OnFormClose(Sender: TObject; var Action: TCloseAction);
   procedure OnFormCloseQuery(Sender: TObject; var CanClose: Boolean);
   procedure OnFormClick(Sender: TObject);
   procedure OnFormDestroy(Sender: TObject);
   procedure OnFormPaint(Sender: TObject);
   procedure OnFormActivate(Sender: TObject);
   procedure OnFormShow(Sender: TObject);
   procedure OnFormHide(Sender: TObject);

  procedure OnFormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);

  procedure OnFormMouseMove(Sender: TObject; Shift: TShiftState; X, Y:Integer);
  procedure OnFormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);

   // ---------------------  component events notify   -----------------------

   procedure  OnMainMenuItemClick(Sender: TObject);
   procedure  OnButtonClick(Sender: TObject);
   procedure  OnCheckBoxClick(Sender: TObject);
   procedure  OnRadioGroupClick(Sender: TObject);
   procedure  OnEditChange(Sender: TObject);
   procedure  OnTrackBarChange(Sender: TObject);
   procedure  OnMemoChange(Sender: TObject);
   procedure  OnListBoxClick(Sender: TObject);
   procedure  OnUpDownClick(Sender: TObject; Button: TUDBtnType);
   procedure  OnSpinEditChange(Sender: TObject);
   procedure  OnComboBoxChange(Sender: TObject);
   procedure  OnPageControlChange(Sender: TObject);
   procedure  OnPopupMenuItemClick(Sender: TObject);

   //---------------------------------------------------------------------

   procedure OnTeeViewChange(Sender: TObject; Node: TTreeNode);
   procedure OnTeeViewClick(Sender: TObject);
   procedure OnTeeViewCollapsed(Sender: TObject; Node: TTreeNode);
   procedure OnTeeViewExpanded(Sender: TObject; Node: TTreeNode);


end;


var g_helper : THelper = nil;




//------------------------------------------------------------------------------
implementation//----------------------------------------------------------------
//------------------------------------------------------------------------------




constructor THelper.Create();
  var sz : integer;
begin
  process_messages_result := True;
  
    f_FuncGuiEventCallBack := nil;
    f_FuncGuiEventCallBack_user_context := nil;

    sz := SizeOf(callback_info);
    sz := 0;
end;

destructor THelper.Destroy;
begin


end;


procedure THelper.Reset( Sender: TObject );
  var cnt : TComponent;
  astr : AnsiString;
begin
  f_callback_info.param1 := 0;
  f_callback_info.param2 := 0;
  f_callback_info.param3 := 0;

  f_callback_info.eventType := EVENT_TYPE_FORM_UNDEFINED;

  cnt := TComponent(Sender);
  f_callback_info.pSender := Pointer(sender);
  f_callback_info.tag := cnt.Tag;

  astr := Sender.className;
  SysUtils.StrLCopy( f_callback_info.class_name , PAnsiChar(astr) , 32 );

  astr := cnt.Name;
  SysUtils.StrLCopy( f_callback_info.name , PAnsiChar(astr) , 32 );


end;

//==============================================================================

procedure THelper.OnMainMenuItemClick(Sender: TObject);
  var cnt : TComponent;
   mi :TMenuItem;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  mi := TMenuItem(Sender);
  f_callback_info.eventType := EVENT_TYPE_MAINMENUITEMCLICK;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure THelper.OnButtonCLick(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_BUTTONCLICK;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure THelper.OnCheckBoxClick(Sender: TObject);
  var cnt : TComponent;
   cb :TCheckBox;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_CHECKBOXCLICK;
  cb := TCheckBox(Sender);
  if cb.Checked then f_callback_info.param1 := 1;


     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure THelper.OnRadioGroupClick(Sender: TObject);
  var cnt : TComponent;
  rg : TRadioGroup;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_RADIOGROUPCLICK;
  rg := TRadioGroup(sender);
  f_callback_info.param1 := rg.ItemIndex;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;


procedure THelper.OnEditChange(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  f_callback_info.eventType := EVENT_TYPE_EDITCHANGE;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure  THelper.OnTrackBarChange(Sender: TObject);
  var cnt : TComponent;
  tb : TTrackBar;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  tb := TTrackBar( sender );
  f_callback_info.param1 := tb.Position;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure  THelper.OnMemoChange(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  f_callback_info.eventType := EVENT_TYPE_MEMOCHANGE;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure  THelper.OnListBoxClick(Sender: TObject);
  var cnt : TComponent;
  lb : TListBox;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  f_callback_info.eventType := EVENT_TYPE_LISTBOXCLICK;
  lb := TListBox( sender );
  f_callback_info.param1 :=  lb.ItemIndex;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure THelper.OnUpDownClick(Sender: TObject; Button: TUDBtnType);
  var cnt : TComponent;
  ud : TUpDown;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  f_callback_info.eventType := EVENT_TYPE_UPDOWNCLICK;
  ud := TUpDown(sender);
  f_callback_info.param1 := Integer(ud.Position);

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure  THelper.OnSpinEditChange(Sender: TObject);
  var cnt : TComponent;
  se :TSpinEdit;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  f_callback_info.eventType := EVENT_TYPE_SPINEDITCHANGE;
  se := TSpinEdit( sender );
  f_callback_info.param1 := se.Value;

     if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure  THelper.OnComboBoxChange(Sender: TObject);
  var cnt : TComponent;
  cb :TComboBox;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_COMBOBOXCHANGE;
  cb := TComboBox(sender);
  f_callback_info.param1 := cb.ItemIndex;
 
    if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;


procedure  THelper.OnPageControlChange(Sender: TObject);
  var cnt : TComponent;
  pc :TPageControl;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_PAGECONTROLCHANGE;
  pc := TPageControl(sender);
  f_callback_info.param1 := pc.TabIndex;

  if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;

procedure  THelper.OnPopupMenuItemClick(Sender: TObject);
  var cnt : TComponent;
  mi :TMenuItem;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  mi := TMenuItem(sender);
    f_callback_info.eventType := EVENT_TYPE_FORM_POPUPMENUITEMCLICK;


  if @self.f_FuncGuiEventCallBack <> nil
     then
        begin
         Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
             @f_callback_info );
        end;

end;





//==============================================================================



procedure THelper.OnFormResize(Sender: TObject);
  var cnt : TComponent;
  frm : TForm;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  frm := TForm(Sender);
  f_callback_info.eventType := EVENT_TYPE_FORM_RESIZE;

  f_callback_info.param1 := frm.Width;
  f_callback_info.param2 := frm.Height;

   if @self.f_FuncGuiEventCallBack <> nil
   then
    begin
     Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
         @f_callback_info );
    end;

end;

procedure THelper.OnFormClose(Sender: TObject; var Action: TCloseAction);
  var cnt : TComponent;
  frm : TForm;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  frm := TForm(Sender);

  f_callback_info.eventType := EVENT_TYPE_FORM_CLOSE;

  //  TCloseAction = (caNone, caHide, caFree, caMinimize);
    Action :=  caHide;



  if @self.f_FuncGuiEventCallBack <> nil
   then
    begin
     Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
         @f_callback_info );
    end;


end;

procedure THelper.OnFormCloseQuery(Sender: TObject; var CanClose: Boolean);
  var cnt : TComponent;
     frm : TForm;
begin
  cnt := TComponent(Sender);
  Reset(sender);
  frm := TForm(Sender);
  f_callback_info.eventType := EVENT_TYPE_FORM_CLOSE_QUERY;

  f_callback_info.param1 := integer(CanClose);
  CanClose := True;


  if @self.f_FuncGuiEventCallBack <> nil
   then
    begin
     Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
         @f_callback_info );
    end;

  if(f_callback_info.param1 <> 0)  then CanClose := True
    else CanClose := false;



end;

procedure THelper.OnFormClick(Sender: TObject);
  var cnt : TComponent;
   frm :TForm;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_FORM_CLICK;
  frm := TForm(sender);


  if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

end;

procedure THelper.OnFormDestroy(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_FORM_DESTROY;

   if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

end;

procedure THelper.OnFormPaint(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_FORM_PAINT;

   if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

end;



procedure THelper.OnFormActivate(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_FORM_ACTIVATE;


   if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;
end;

procedure THelper.OnFormShow(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_FORM_SHOW;

   if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

end;

procedure THelper.OnFormHide(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_FORM_HIDE;

   if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

end;


procedure THelper.OnFormMouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_FORM_MOUSEDOWN;

  f_callback_info.param1 := X;
  f_callback_info.param2 := Y;
  f_callback_info.param2 :=  Integer(Button);

     if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;
  

end;

procedure THelper.OnFormMouseMove(Sender: TObject; Shift: TShiftState; X, Y:Integer);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_FORM_MOUSEMOVE;

  f_callback_info.param1 := X;
  f_callback_info.param2 := Y;
  //f_callback_info.param2 :=  Integer(Button);


     if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;


end;

procedure THelper.OnFormMouseUp(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);


  f_callback_info.eventType := EVENT_TYPE_FORM_MOUSEUP;

  f_callback_info.param1 := X;
  f_callback_info.param2 := Y;
  f_callback_info.param2 :=  Integer(Button);


     if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

 
end;



//==============================================================================
procedure THelper.OnTeeViewChange(Sender: TObject; Node: TTreeNode);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

  f_callback_info.eventType := EVENT_TYPE_TREEVIEW_CHANGE;
  f_callback_info.param1 := Integer( Node );

     if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;
end;

procedure THelper.OnTeeViewClick(Sender: TObject);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_TREEVIEW_CLICK;

     if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;
end;

procedure THelper.OnTeeViewCollapsed(Sender: TObject; Node: TTreeNode);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_TREEVIEW_COLLAPSED;
   f_callback_info.param1 := Integer( Node );


     if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

end;

procedure THelper.OnTeeViewExpanded(Sender: TObject; Node: TTreeNode);
  var cnt : TComponent;
begin
  cnt := TComponent(Sender);
  Reset(sender);

   f_callback_info.eventType := EVENT_TYPE_TREEVIEW_EXPANDED;

   f_callback_info.param1 := Integer( Node );


     if @self.f_FuncGuiEventCallBack <> nil
     then
      begin
       Self.f_FuncGuiEventCallBack(Self.f_FuncGuiEventCallBack_user_context,
           @f_callback_info );
      end;

end;






//==============================================================================


procedure SetGuiEventCallBack( func : FuncGuiEventCallBack;
            user_context :pointer); stdcall;
begin
    g_helper.f_FuncGuiEventCallBack := func;
    g_helper.f_FuncGuiEventCallBack_user_context := user_context;

end;

procedure SetFormOnResize(pForm :Pointer; func :FuncOnResizeForm;
                                  user_context :pointer); stdcall;
  var frm :TForm;
begin
  frm := TForm( pForm );
  frm.OnResize := g_helper.OnFormResize;


end;

procedure PostExit(code :integer); stdcall;
begin
  g_helper.process_messages_result := false;
end;







//=============================================================================

initialization
  if g_helper = nil
    then g_helper := THelper.Create;


finalization
  //FreeAndNil(g_helper);

end.
